{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from __future__ import division, print_function"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the saved Keras 1.2 model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rm: mnist_cnn_allconv_tensorflow.h5: No such file or directory\n",
      "--2018-06-05 22:07:45--  https://raw.githubusercontent.com/AvantiShri/model_storage/cca175f988023e62b7a2939f151034d38a83c4d3/deeplift/mnist/mnist_cnn_allconv_tensorflow.h5\n",
      "Resolving raw.githubusercontent.com... 151.101.188.133\n",
      "Connecting to raw.githubusercontent.com|151.101.188.133|:443... connected.\n",
      "HTTP request sent, awaiting response... 200 OK\n",
      "Length: 979776 (957K) [application/octet-stream]\n",
      "Saving to: 'mnist_cnn_allconv_tensorflow.h5'\n",
      "\n",
      "100%[======================================>] 979,776     --.-K/s   in 0.08s   \n",
      "\n",
      "2018-06-05 22:07:45 (11.1 MB/s) - 'mnist_cnn_allconv_tensorflow.h5' saved [979776/979776]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!rm mnist_cnn_allconv_tensorflow.h5\n",
    "!wget https://raw.githubusercontent.com/AvantiShri/model_storage/cca175f988023e62b7a2939f151034d38a83c4d3/deeplift/mnist/mnist_cnn_allconv_tensorflow.h5 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Inspect the json and weights of the saved file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "keras version 1.2.0\n",
      "keras json {\n",
      "    \"class_name\": \"Sequential\", \n",
      "    \"config\": [\n",
      "        {\n",
      "            \"class_name\": \"Convolution2D\", \n",
      "            \"config\": {\n",
      "                \"W_constraint\": null, \n",
      "                \"b_constraint\": null, \n",
      "                \"name\": \"convolution2d_1\", \n",
      "                \"activity_regularizer\": null, \n",
      "                \"trainable\": true, \n",
      "                \"dim_ordering\": \"tf\", \n",
      "                \"nb_col\": 4, \n",
      "                \"subsample\": [\n",
      "                    2, \n",
      "                    2\n",
      "                ], \n",
      "                \"init\": \"glorot_uniform\", \n",
      "                \"bias\": true, \n",
      "                \"nb_filter\": 32, \n",
      "                \"activation\": \"linear\", \n",
      "                \"input_dtype\": \"float32\", \n",
      "                \"b_regularizer\": null, \n",
      "                \"W_regularizer\": null, \n",
      "                \"nb_row\": 4, \n",
      "                \"batch_input_shape\": [\n",
      "                    null, \n",
      "                    28, \n",
      "                    28, \n",
      "                    1\n",
      "                ], \n",
      "                \"border_mode\": \"valid\"\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Activation\", \n",
      "            \"config\": {\n",
      "                \"activation\": \"relu\", \n",
      "                \"trainable\": true, \n",
      "                \"name\": \"activation_1\"\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Convolution2D\", \n",
      "            \"config\": {\n",
      "                \"W_constraint\": null, \n",
      "                \"b_constraint\": null, \n",
      "                \"name\": \"convolution2d_2\", \n",
      "                \"activity_regularizer\": null, \n",
      "                \"trainable\": true, \n",
      "                \"dim_ordering\": \"tf\", \n",
      "                \"nb_col\": 4, \n",
      "                \"subsample\": [\n",
      "                    2, \n",
      "                    2\n",
      "                ], \n",
      "                \"init\": \"glorot_uniform\", \n",
      "                \"bias\": true, \n",
      "                \"nb_filter\": 64, \n",
      "                \"b_regularizer\": null, \n",
      "                \"W_regularizer\": null, \n",
      "                \"nb_row\": 4, \n",
      "                \"activation\": \"linear\", \n",
      "                \"border_mode\": \"valid\"\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Activation\", \n",
      "            \"config\": {\n",
      "                \"activation\": \"relu\", \n",
      "                \"trainable\": true, \n",
      "                \"name\": \"activation_2\"\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Dropout\", \n",
      "            \"config\": {\n",
      "                \"p\": 0.25, \n",
      "                \"trainable\": true, \n",
      "                \"name\": \"dropout_1\"\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Flatten\", \n",
      "            \"config\": {\n",
      "                \"trainable\": true, \n",
      "                \"name\": \"flatten_1\"\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Dense\", \n",
      "            \"config\": {\n",
      "                \"W_constraint\": null, \n",
      "                \"b_constraint\": null, \n",
      "                \"name\": \"dense_1\", \n",
      "                \"activity_regularizer\": null, \n",
      "                \"trainable\": true, \n",
      "                \"init\": \"glorot_uniform\", \n",
      "                \"bias\": true, \n",
      "                \"input_dim\": 1600, \n",
      "                \"b_regularizer\": null, \n",
      "                \"W_regularizer\": null, \n",
      "                \"activation\": \"linear\", \n",
      "                \"output_dim\": 128\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Activation\", \n",
      "            \"config\": {\n",
      "                \"activation\": \"relu\", \n",
      "                \"trainable\": true, \n",
      "                \"name\": \"activation_3\"\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Dropout\", \n",
      "            \"config\": {\n",
      "                \"p\": 0.5, \n",
      "                \"trainable\": true, \n",
      "                \"name\": \"dropout_2\"\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Dense\", \n",
      "            \"config\": {\n",
      "                \"W_constraint\": null, \n",
      "                \"b_constraint\": null, \n",
      "                \"name\": \"dense_2\", \n",
      "                \"activity_regularizer\": null, \n",
      "                \"trainable\": true, \n",
      "                \"init\": \"glorot_uniform\", \n",
      "                \"bias\": true, \n",
      "                \"input_dim\": 128, \n",
      "                \"b_regularizer\": null, \n",
      "                \"W_regularizer\": null, \n",
      "                \"activation\": \"linear\", \n",
      "                \"output_dim\": 10\n",
      "            }\n",
      "        }, \n",
      "        {\n",
      "            \"class_name\": \"Activation\", \n",
      "            \"config\": {\n",
      "                \"activation\": \"softmax\", \n",
      "                \"trainable\": true, \n",
      "                \"name\": \"activation_4\"\n",
      "            }\n",
      "        }\n",
      "    ]\n",
      "} \n",
      "\n",
      "layer weight names: [u'convolution2d_1/convolution2d_1_W_2:0', u'convolution2d_1/convolution2d_1_b_2:0', u'convolution2d_2/convolution2d_2_W_2:0', u'convolution2d_2/convolution2d_2_b_2:0', u'dense_1/dense_1_W_2:0', u'dense_1/dense_1_b_2:0', u'dense_2/dense_2_W_2:0', u'dense_2/dense_2_b_2:0'] \n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/avantishrikumar/anaconda/lib/python2.7/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
      "  from ._conv import register_converters as _register_converters\n"
     ]
    }
   ],
   "source": [
    "import h5py\n",
    "import json\n",
    "f = h5py.File(\"mnist_cnn_allconv_tensorflow.h5\")\n",
    "print(\"keras version\", f.attrs['keras_version'])\n",
    "print(\"keras json\", json.dumps(json.loads(f.attrs['model_config']),\n",
    "                               indent=4),\"\\n\")\n",
    "print(\"layer weight names:\", [layer_name+\"/\"+x\n",
    "                              for layer_name in f['model_weights'].keys()\n",
    "                              for x in f['model_weights'][layer_name].attrs['weight_names']],\"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Couldn't import dot_parser, loading of dot files will not be possible.\n",
      "keras version 2.1.6\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import keras\n",
    "print (\"keras version\",keras.__version__)\n",
    "import numpy as np\n",
    "\n",
    "#create a keras 2 model with the same architecture\n",
    "#set the weights for each layer using the hdf5\n",
    "#weights file\n",
    "model = keras.models.Sequential()\n",
    "model.add(keras.layers.Conv2D(filters=32, kernel_size=(4,4),\n",
    "                              strides=(2,2),\n",
    "                              input_shape=(28,28,1)))\n",
    "model.add(keras.layers.Activation(\"relu\"))\n",
    "model.add(keras.layers.Conv2D(filters=64, kernel_size=(4,4),\n",
    "                              strides=(2,2)))\n",
    "model.add(keras.layers.Activation(\"relu\"))\n",
    "model.add(keras.layers.Dropout(0.25))\n",
    "model.add(keras.layers.Flatten())\n",
    "model.add(keras.layers.Dense(units=128))\n",
    "model.add(keras.layers.Activation(\"relu\"))\n",
    "model.add(keras.layers.Dropout(0.5))\n",
    "model.add(keras.layers.Dense(units=10))\n",
    "model.add(keras.layers.Activation(\"softmax\"))\n",
    "model.build()\n",
    "\n",
    "#load the weights into each layer\n",
    "\n",
    "#first convolution\n",
    "model.layers[0].set_weights(\n",
    "    [np.array(f['model_weights']['convolution2d_1/convolution2d_1_W_2:0']),\n",
    "     np.array(f['model_weights']['convolution2d_1/convolution2d_1_b_2:0'])])\n",
    "#second convolution\n",
    "model.layers[2].set_weights(\n",
    "    [np.array(f['model_weights']['convolution2d_2/convolution2d_2_W_2:0']),\n",
    "     np.array(f['model_weights']['convolution2d_2/convolution2d_2_b_2:0'])])\n",
    "#first dense layer\n",
    "model.layers[6].set_weights(\n",
    "    [np.array(f['model_weights']['dense_1/dense_1_W_2:0']),\n",
    "     np.array(f['model_weights']['dense_1/dense_1_b_2:0'])])\n",
    "#second dense layer\n",
    "model.layers[9].set_weights(\n",
    "    [np.array(f['model_weights']['dense_2/dense_2_W_2:0']),\n",
    "     np.array(f['model_weights']['dense_2/dense_2_b_2:0'])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Verify the accuracy obtained on MNIST"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy: 0.9921\n"
     ]
    }
   ],
   "source": [
    "from keras.datasets import mnist\n",
    "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
    "X_test = X_test[:,:,:,None]\n",
    "\n",
    "predictions = model.predict(X_test)\n",
    "print(\"accuracy:\",float(np.sum(np.argmax(predictions, axis=1)==y_test))/len(y_test))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Save the converted model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "model.save(\"keras2_mnist_cnn_allconv.h5\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
